package Interfaces;

import Consulta.DB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import Imprimibles.Padre;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPTable;
import java.io.File;
import java.sql.ResultSetMetaData;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
 *
 * @author Jose Martinez
 */
public class Factura extends javax.swing.JFrame {

    /** Creates new form Factura */
    private manejadorDB db = new manejadorDB();
    private List<String[]> listaMateriales = new ArrayList<String[]>();
    private String[] idAutorizador;
    private String nombreAutorizo = "";
    private Integer idEmpleado, idAlmacen, idAuto;

    public Factura(Integer idEmpleado, Integer idAlmacen) {
        initComponents();
        submit.setEnabled(false);
        add.setEnabled(false);
        this.idEmpleado = idEmpleado;
        this.idAlmacen = idAlmacen;
        setNombreMaterial();
        comprobarDatos cD = new comprobarDatos(codigo, nombreMaterial, cantidad, add, submit);
        cD.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        codigo = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        unidad = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        cantidad = new javax.swing.JTextField();
        add = new javax.swing.JButton();
        submit = new javax.swing.JButton();
        nombreMaterial = new javax.swing.JComboBox();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("Codigo");

        codigo.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                codigoFocusLost(evt);
            }
        });

        jLabel2.setText("Nombre");

        jLabel3.setText("Unidad");

        unidad.setEditable(false);

        jLabel4.setText("Cantidad");

        add.setText("+");
        add.setDoubleBuffered(true);
        add.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addActionPerformed(evt);
            }
        });

        submit.setText("OK");
        submit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                submitActionPerformed(evt);
            }
        });

        nombreMaterial.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nombreMaterialActionPerformed(evt);
            }
        });

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(codigo, javax.swing.GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
                    .addComponent(unidad, javax.swing.GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
                    .addComponent(cantidad, javax.swing.GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(add, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(submit, javax.swing.GroupLayout.DEFAULT_SIZE, 94, Short.MAX_VALUE))
                    .addComponent(nombreMaterial, 0, 142, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(codigo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(nombreMaterial, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(unidad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(cantidad, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 21, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(add)
                    .addComponent(submit))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void codigoFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_codigoFocusLost
        // TODO add your handling code here:
        if (codigo.getText().isEmpty()) {
            return;
        }
        Map<Integer, String[]> tempMap = db.getAtributosMateriales(Integer.parseInt(codigo.getText()));
        if (!tempMap.isEmpty()) {
            for (Map.Entry<Integer, String[]> dic : tempMap.entrySet()) {
                nombreMaterial.setSelectedItem(dic.getValue()[0]);
                unidad.setText(dic.getValue()[1]);
            }
        }
    }//GEN-LAST:event_codigoFocusLost

    private void addActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addActionPerformed
        // TODO add your handling code here:
        add.setEnabled(false);
        submit.setEnabled(false);
        llenarLista();
        limpiarCampos();
    }//GEN-LAST:event_addActionPerformed

    private void submitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_submitActionPerformed
        // TODO add your handling code here:
        llenarLista();
        String[] temp = db.autorizadoPor();
        String opcionAutorizado = (String) JOptionPane.showInputDialog(this, "Autorizado Por", "EDENORTE", JOptionPane.QUESTION_MESSAGE, null, temp, null);
        nombreAutorizo = opcionAutorizado;
        if (opcionAutorizado != null) {
            idAuto = Integer.parseInt(idAutorizador[Arrays.binarySearch(temp, opcionAutorizado)]);
            db.insertar();
        } else {
            JOptionPane.showMessageDialog(this, "Error elija quien lo autorizo");
        }
    }//GEN-LAST:event_submitActionPerformed

    private void nombreMaterialActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nombreMaterialActionPerformed
        // TODO add your handling code here:
        manejadorDB mDB = new manejadorDB();
        String data[] = mDB.getDataByName(nombreMaterial.getSelectedItem().toString());
        populateFielda(data);
    }//GEN-LAST:event_nombreMaterialActionPerformed
    /**
     * @param args the command line arguments
     */
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton add;
    private javax.swing.JTextField cantidad;
    private javax.swing.JTextField codigo;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JComboBox nombreMaterial;
    private javax.swing.JButton submit;
    private javax.swing.JTextField unidad;
    // End of variables declaration//GEN-END:variables

    private void setNombreMaterial() {

        nombreMaterial.addItem("");
        for (String s : db.getNombreMateriales()) {
            nombreMaterial.addItem(s);
        }
    }

    private void llenarLista() {
        String[] arrtemp = new String[4];
        arrtemp[0] = (String) nombreMaterial.getSelectedItem();
        arrtemp[1] = cantidad.getText();
        arrtemp[2] = unidad.getText();
        arrtemp[3] = codigo.getText();
        listaMateriales.add(arrtemp);
    }

    private void limpiarCampos() {
        codigo.setText("");
        nombreMaterial.setSelectedItem("");
        unidad.setText("");
        cantidad.setText("");
    }

    private void populateFielda(String[] data) {
        codigo.setText(data[0]);
        unidad.setText(data[1]);
    }

    class manejadorDB extends DB {

        public manejadorDB() {
        }

        public List<String> getNombreMateriales() {
            List<String> resultadoList = new ArrayList<String>();
            conectarDB();
            try {
                rs = stmt.executeQuery("select nombre from Materiales");
                while (rs.next()) {
                    resultadoList.add(rs.getString("nombre"));
                }
            } catch (Exception e) {
            } finally {
                desconectarDB();
                return resultadoList;
            }
        }

        public Map<Integer, String[]> getAtributosMateriales(Integer numIdentificacion) {
            Map<Integer, String[]> resultadoMap = new HashMap<Integer, String[]>();
            conectarDB();
            try {
                rs = stmt.executeQuery("select idMaterial,nombre,unidad from "
                        + "Materiales where NoIdentificacion = '" + numIdentificacion + "'");
                String[] tempString = new String[2];
                while (rs.next()) {
                    tempString[0] = rs.getString("nombre");
                    tempString[1] = rs.getString("unidad");
                    resultadoMap.put(rs.getInt("idMaterial"), tempString);
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                desconectarDB();
                return resultadoMap;
            }
        }

        public void insertar() {
            conectarDB();
            try {
                conn.setAutoCommit(false);
                rs = stmt.executeQuery("select max(idVale) as MAX from Vales");
                ResultSetMetaData rsmd = rs.getMetaData();
                System.out.println(rsmd.isNullable(1));
                Integer idVale = 0, idMaterial = 0;
                while (rs.next()) {
                    idVale = rs.getInt("MAX") + 1;
                }
                //System.out.println(idVale);
                //System.out.println(idEmpleado + "b" + idAlmacen + " " + idAuto);
                stmt.executeUpdate("insert into Vales values(" + idVale + ",curdate()," + idEmpleado + ", " + idAlmacen + "," + idAuto + ")");
                for (String[] arr : listaMateriales) {
                    rs = stmt.executeQuery("select idMaterial from Materiales where Nombre = '" + arr[0] + "'");
                    while (rs.next()) {
                        idMaterial = rs.getInt("idMaterial");
                    }
                    stmt.executeUpdate("insert into DetalleVale values(" + idVale + ""
                            + "," + idMaterial + ", " + Integer.parseInt(arr[1]) + ")");
                }
                conn.commit();
                generarReporte();
            } catch (Exception e) {
                try {
                    System.out.println(e.getMessage());
                    conn.rollback();
                } catch (SQLException ex) {
                    Logger.getLogger(Factura.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    desconectarDB();
                }
            }
        }

        public String[] autorizadoPor() {
            conectarDB();
            String[] auto = null;
            try {
                rs = stmt.executeQuery("Select idEmpleado, CONCAT(E.Nombre, \" \", E.Apellido) "
                        + "as NombreCompleto from Empleados E");
                ResultSetMetaData rsmd = rs.getMetaData();
                int cont = 0,rowCount = 0;
                rs.last();
                rowCount = rs.getRow();
                rs.first();
                auto = new String[rowCount];
                idAutorizador = new String[rowCount];
                while (rs.next()) {
                    auto[cont] = rs.getString("NombreCompleto");
                    idAutorizador[cont] = rs.getString("idEmpleado");
                    cont++;
                }
            } catch (Exception e) {
            } finally {
                desconectarDB();
                return auto;
            }
        }

        public void generarReporte() {
            conectarDB();
            String[] infoPrincipal = new String[6];
            try {
                rs = stmt.executeQuery("select idVale as NoVale, Fecha as "
                        + "Fecha, CONCAT(Nombre, \" \", Apellido) as NombreEmpleado, NoCarnet as NoCarnet"
                        + " from Vales, Empleados where "
                        + "Vales.Empleado = Empleados.idEmpleado and idVale = "
                        + "(Select MAX(idVale) from Vales)");
                while (rs.next()) {
                    infoPrincipal[0] = rs.getString("NoVale");
                    infoPrincipal[1] = rs.getString("Fecha");
                    infoPrincipal[2] = rs.getString("NombreEmpleado");
                    infoPrincipal[3] = rs.getString("NoCarnet");
                }
                infoPrincipal[4] = nombreAutorizo;
                infoPrincipal[5] = " ";
                imprimirReporte imprimirReporte = new imprimirReporte();
                imprimirReporte.formatoImprimible(listaMateriales, infoPrincipal);
                imprimirReporte.imprimir(new File("./tempImprimible.pdf"));
            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                desconectarDB();
            }

        }

        private String[] getDataByName(String Nombre) {
            conectarDB();
            String[] result = new String[2];
            try {
                rs = stmt.executeQuery("Select NoIdentificacion, Unidad from "
                        + "Materiales where Nombre ='" + Nombre + "'");
                while (rs.next()) {
                    result[0] = rs.getString("NoIdentificacion");
                    result[1] = rs.getString("Unidad");
                }
            } catch (Exception e) {
            } finally {
                desconectarDB();
                return result;
            }
        }
    }

    class imprimirReporte extends Padre {

        public imprimirReporte() {
        }

        public void formatoImprimible(List<String[]> entradaList, String[] encabezado) {
            String[] Heading = {"No. Vale", "Fecha", "Nombre Empleado", "No. Carnet", "Autorizado Por", " "};
            String[] Heading2 = {"Codigo", "Unidad", "Descripcion Material", "Cantidad"};
            String[] Heading3 = {"AUTORIZADO POR ENCARGADO", "DESPACHADO POR EMPLEADO", "RECIBIDO POR EMPLEADO"};
            try {
                crearPDF();
                documento.open();
                Paragraph espaciosParagraph = new Paragraph("\n");
                Paragraph p = new Paragraph("Despacho Manual");
                p.setAlignment("Center");
                documento.add(p);
                documento.add(espaciosParagraph);
                documento.add(espaciosParagraph);
                PdfPTable table = new PdfPTable(4);
                for (int i = 0; i < Heading.length; i++) {
                    table.addCell(Heading[i]);
                    table.addCell(encabezado[i]);
                }
                documento.add(table);
                documento.add(espaciosParagraph);
                documento.add(espaciosParagraph);
                PdfPTable table2 = new PdfPTable(4);
                for (String s : Heading2) {
                    table2.addCell(s);
                }
                for (String[] strings : entradaList) {
                    table2.addCell(strings[3]);
                    table2.addCell(strings[2]);
                    table2.addCell(strings[0]);
                    table2.addCell(strings[1]);
                }
                documento.add(table2);
                documento.add(espaciosParagraph);
                documento.add(espaciosParagraph);
                p = new Paragraph("ESTE DESPACHO ES PROVICIONAL SU DURACION ES DE 72 HORAS, DE LO CONTRARIO SE APLICARA A CUALQUIER RESERVA EXISTENTE");
                p.setAlignment("Center");
                documento.add(p);
                PdfPTable tabla3 = new PdfPTable(3);
                for (int i = 0; i < 3; i++) {
                    tabla3.addCell(" ");
                }
                for (String s : Heading3) {
                    tabla3.addCell(s);
                }
                documento.add(espaciosParagraph);
                documento.add(espaciosParagraph);
                documento.add(espaciosParagraph);
                documento.add(tabla3);
            } catch (DocumentException de) {
                System.err.println(de.getMessage());
            } finally {
                cerrarPDF();
            }
        }
    }

    class comprobarDatos extends Thread {

        private JTextField codigo, cantidad;
        private JComboBox nombre;
        private JButton submit, add;

        public comprobarDatos(JTextField codigo, JComboBox nombre, JTextField cantidad, JButton submit, JButton add) {
            this.codigo = codigo;
            this.nombre = nombre;
            this.cantidad = cantidad;
            this.submit = submit;
            this.add = add;
        }

        @Override
        public void run() {
            checkFields();
        }

        private void checkFields() {
            while (true) {
                if ((!codigo.getText().isEmpty() || !nombre.getSelectedItem().toString().isEmpty()) && !cantidad.getText().isEmpty()) {
                    submit.setEnabled(true);
                    add.setEnabled(true);
                } else {
                    submit.setEnabled(false);
                    add.setEnabled(false);
                }
            }
        }
    }
}